home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / fdimg / —‹Œêsrc.lzh / disp.c < prev    next >
C/C++ Source or Header  |  1993-03-18  |  22KB  |  1,050 lines

  1. #include    "3DDEF.H"
  2. #include    "GLOBAL.H"
  3. #include    "FORWARD.H"
  4. #include    "XCODE.H"
  5. #include    "doslib.h"
  6.  
  7. /* 画面制御 */
  8.  
  9. /* チェックして、必要ならば画面にエコーする */
  10. /* 行の文字列が変更を受けたのでアップデートするのだ */
  11. void
  12. disp_check_1line_echo(register UNIT *tp)
  13. {
  14.     register short int i;
  15.     register UNIT **s,*p;
  16.  
  17.     for(s=SCREEN,i=0;i<YWIDTH-1;s++,i++) {
  18.         if ((p = *s) == tp) {
  19.             disp_1line(i,tp);
  20.         }
  21.     }
  22. }
  23.  
  24. /* チェックして、必要ならば画面にエコーする */
  25. /* 挿入である */
  26. void
  27. disp_check_1line_insert(UNIT *line,register UNIT *tp)
  28. {
  29.     register short int i;
  30.     register UNIT **s,*p;
  31.  
  32.     for(s=SCREEN,i=0;i<YWIDTH;s++,i++) {
  33.         if (*s == tp) {
  34. /*            *s = line;*/
  35.             disp_1line(i,line);
  36.  
  37.             while(s[1] != NOT) {    /* 下の行が、空行もしくは何かある */
  38.                 i++;
  39.                 if ((p = (*s++)->ATO) == NIL) break;
  40.                         /* 空行ならもう終わり */
  41.                 disp_1line(i,p);
  42. /*                *s = p;*/
  43.             }
  44.         }
  45.     }
  46. }
  47.  
  48. static UBYTE disp_work[VERY_LONG_LINE];
  49.  
  50. /* 1行だけ y の位置に表示する */
  51. /* y は絶対座標である */
  52. void
  53. disp_1line(int y, UNIT *unit_pointer)
  54. {
  55.     int x;
  56.  
  57.     if (unit_pointer) {
  58.         line_get_body(disp_work,unit_pointer);
  59.         etc_bit_convert_and_disp(0,y,disp_work);
  60.     } else {
  61.         etc_bit_convert_and_disp(0,y,"");
  62.     }
  63.     SCREEN[y] = unit_pointer;            /* スクリーン更新 */
  64. }
  65.  
  66. /* 1行だけカレントウインドウの y(相対) の位置に表示する */
  67. void
  68. disp_1line_rel(int y, UNIT *unit_pointer)
  69. {
  70.     disp_1line(CWY0+y,unit_pointer);
  71. }
  72.  
  73. UBYTE BOTTOM_FORMAT0[] = "===== ThunderWord V1.24 \
  74. ========================================================================";
  75. UBYTE BOTTOM_FORMAT1[] = "----- ThunderWord V1.24 \
  76. ------------------------------------------------------------------------";
  77.  
  78. /*
  79. ================================================================================================
  80. =***= ThunderWord V0.4 ==[全角:ひら:ROMA:無変]== 0123456789abcdefgh.zzz =========================
  81. ^    ^    ^    ^    ^    ^    ^    ^    ^    ^    ^    ^    
  82. 0    8    16    24    32    40    48    56    64    72    80    88
  83.             =[半角:カタ:通常:変換]=
  84. */
  85.  
  86. /* カレントテキストに changed mark を付ける */
  87. /* カレントテキストを表示しているすべてのウインドウに対して行う */
  88. void
  89. disp_btm_changed_10()
  90. {
  91.     disp_cursor_off();
  92.     if (CURRENT_CHANGED) {
  93.         disp_btm_changed_x(CURRENT_TEXT);
  94.     } else {
  95.         disp_btm_changed_erase_x(CURRENT_TEXT);
  96.     }
  97. }
  98.  
  99. /* カレントテキストに changed mark を付ける */
  100. /* カレントテキストを表示しているすべてのウインドウに対して行う */
  101. void
  102. disp_btm_changed()
  103. {
  104.     disp_cursor_off();
  105.     if (!CURRENT_CHANGED) {
  106.         disp_btm_changed_x(CURRENT_TEXT);
  107.         CURRENT_CHANGED = 1;
  108.     }
  109. }
  110.  
  111. /* テキストに bak mode を表示する */
  112. /* テキストを表示しているすべてのウインドウに対して行う */
  113. void
  114. disp_btm_bak_10_x(int tn)
  115. {
  116.     disp_cursor_off();
  117.     if (TDATA[tn].BAK_FLAG) {
  118.         disp_btm_changed_x_sub(tn,3,'B');
  119.     } else {
  120.         disp_btm_changed_x_sub(tn,3,'\0');
  121.     }
  122. }
  123.  
  124. /* テキストに changed mark を付ける */
  125. /* テキストを表示しているすべてのウインドウに対して行う */
  126. void
  127. disp_btm_changed_10_x(int tn)
  128. {
  129.     disp_cursor_off();
  130.     if (TDATA[tn].CHANGED_FLAG) {
  131.         disp_btm_changed_x(tn);
  132.     } else {
  133.         disp_btm_changed_erase_x(tn);
  134.     }
  135. }
  136.  
  137. /* 指定されたテキストに changed mark を付ける */
  138. /* そのテキストを表示しているすべてのウインドウに対して行う */
  139. void
  140. disp_btm_changed_x(int tn)
  141. {
  142.     disp_btm_changed_x_sub(tn,1,'*');
  143. }
  144.  
  145. void
  146. disp_btm_changed_x_sub(int tn,int x,UBYTE c)
  147. {
  148.     register int i;
  149.     UBYTE wlist[MAX_WINDOW];    /* フラグ用 */
  150.  
  151.     window_which_has_text_number(tn,wlist);
  152.  
  153.     disp_cursor_off();
  154.     etc_color(MIZU_EMPH_REV);
  155.     for(i = 0;i < MAX_WINDOW;i++) {
  156.         if (wlist[i]) {    /* そのテキストが割り当てられているウインドウである */
  157.             window_abs_loc(x,WDATA[i].WY1+1);
  158.             if (c) {
  159.                 B_PUTC(c);
  160.             } else if (i == CWN) {
  161.                 B_PUTC('=');
  162.             } else {
  163.                 B_PUTC('-');
  164.             }
  165.         }
  166.     }
  167.     etc_color(NORMAL);
  168. }
  169.  
  170. /* カレントから changed mark を外す */
  171. /* カレントテキストを表示しているすべてのウインドウに対して行う */
  172. void
  173. disp_btm_changed_erase_x(int tn)
  174. {
  175.     disp_btm_changed_x_sub(tn,1,'\0');
  176. }
  177.  
  178. /* 指定されたウインドウの、BOTTOM を表示する */
  179.  
  180. void
  181. disp_btm_line(int wn)
  182. {
  183.     UBYTE work[MAXLINE];
  184.     UBYTE work2[MAXLINE];
  185.     UBYTE w[5];
  186.     int i,x;
  187.  
  188.     /* 元をコピー */
  189.     if (wn == CWN) {
  190.         strcpy(work,BOTTOM_FORMAT0);
  191.     } else {
  192.         strcpy(work,BOTTOM_FORMAT1);
  193.     }
  194.  
  195.     if (i = strlen(FILE_NAMES_ST[WDATA[wn].WTEXTS].CONTENT)) {
  196. /*    if (i = strlen(FILE_NAMES[WDATA[wn].WTEXTS].CONTENT)) {*/
  197.         int j;
  198.         strncpy(&work[49],FILE_NAMES_ST[WDATA[wn].WTEXTS].CONTENT,i);
  199.         work[48] = ' ';
  200.         if (i+49 < XWIDTH) {
  201.             work[49+i] = ' ';
  202.             strcpy(&work2[1],FILE_NAMES[WDATA[wn].WTEXTS].CONTENT);
  203. /*            etc_get_pathname(&work2[1],FILE_NAMES[WDATA[wn].WTEXTS].CONTENT);*/
  204.             if (work2[1]) {
  205.                 *work2 = ' ';
  206.                 strcat(work2," ");
  207.             } else {
  208.                 *work2 = EOS;
  209.             }
  210.         } else {
  211.             *work2 = EOS;
  212.         }
  213.         j = strlen(work2);
  214.         if (j > XWIDTH-(49+i+3)+1) {    /* 長過ぎるのでカット */
  215.             j = XWIDTH-(49+i+3)-1;
  216.             work[XWIDTH-1] = '$';
  217.         } else {
  218.             strncpy(&work[49+i+3],work2,j);
  219.         }
  220.         work[XWIDTH] = EOS;
  221.     } else {
  222.         return;
  223.     }
  224.  
  225.     if (WDATA[wn].WY1+2 == UNDER_Y) {
  226.         strncpy(&work[25],"[    :    :    :    ]",46-25);
  227. /*        strncpy(&work[25],"[全角:カタ:かな:変換]",46-25);*/
  228. /*        strncpy(&work[25],"[半角:----:----:無変]",46-25);*/
  229.         for(i = 0,x = 26;x <= 41;i++,x += 5) {
  230.             if (FP_MODE[i] == (UBYTE)"ZKRM"[i]) {
  231.                 strncpy(&work[x],&("全角かなROMA無変"[i*4]),4);
  232.             } else {
  233.                 strncpy(&work[x],&("半角--------変換"[i*4]),4);
  234.             }
  235.         }
  236.     }
  237.     etc_color(MIZU_EMPH_REV);
  238.     disp_btm_line0(wn,work);
  239.     disp_btm_changed_10_x(WDATA[wn].WTEXTS);
  240.     disp_btm_bak_10_x(WDATA[wn].WTEXTS);
  241.     etc_color(NORMAL);
  242. }
  243.  
  244. /* 指定されたウインドウの、BOTTOM の位置に文字列を表示する */
  245. void
  246. disp_btm_line0(int wn, STR s)
  247. {
  248.     disp_cursor_off();
  249.     window_abs_loc(0,WDATA[wn].WY1+1);
  250.     B_PRINT(s);
  251.     SCREEN[WDATA[wn].WY1+1] = NOT;        /* -1 */
  252.     fep_follow_led();
  253. }
  254.  
  255. void
  256. disp_show_cursor()
  257. {
  258.     B_BPOKE(0x991,0);    /* OFF フラグをセット */
  259.     B_WPOKE(0x9bc,1);    /* ダウンカウンタを1に */
  260. }
  261.  
  262. void
  263. disp_cursor_off()
  264. {
  265.     B_CUROFF();
  266. }
  267.  
  268. void
  269. disp_cursor_on()
  270. {
  271.     B_CURON();
  272. }
  273.  
  274. /* CL がウインドウの中心-1行に来るように書き直す */
  275. void
  276. disp_cl_center_1()
  277. {
  278.     disp_cl_y((CWY1-CWY0)/2-1);
  279. }
  280.  
  281. /* CL がウインドウの中心に来るように書き直す */
  282. void
  283. disp_cl_center()
  284. {
  285.     disp_cl_y((CWY1-CWY0)/2);
  286. }
  287.  
  288. /* CL がウインドウの y 行目に来るように書き直す */
  289. void
  290. disp_cl_y(int y)
  291. {
  292.     int movel;
  293.  
  294.     disp_top_flush(line_trace(CL,-y,&movel));
  295.     CY = -movel;
  296. }
  297.  
  298. /* 指定された行を最上行として画面を書き直す */
  299. void
  300. disp_top_flush(UNIT *top)
  301. {
  302.     disp_middle_flush(0,top);
  303. }
  304.  
  305. /* 指定された行を i 行として以下の画面を書き直す */
  306. void
  307. disp_middle_flush(int t,UNIT *top)
  308. {
  309.     int i;
  310.  
  311.     for(i = 0;i < t;i++);
  312.     for(;i <= CWY1 - CWY0;i++) {
  313.         disp_1line_rel(i,top);
  314.         if (top) {
  315.             if (top == TAIL) {
  316.                 top = NIL;
  317.             } else {
  318.                 top = top->ATO;
  319.             }
  320.         }
  321.     }
  322. }
  323.  
  324. /* 前を後で置き換える */
  325. void
  326. disp_replace(UNIT *d,UNIT *s)
  327. {
  328.     register int i;
  329.     register UNIT **sc;
  330.  
  331.     for(sc=SCREEN,i=0;i<YWIDTH;sc++,i++) {
  332.         if (*sc == d) {
  333.             disp_1line(i,s);
  334.         }
  335.     }
  336. }
  337.  
  338. /* SCREEN[] で、前を後で置き換える */
  339. void
  340. disp_replace_SCREEN(UNIT *d,UNIT *s)
  341. {
  342.     register int i;
  343.     register UNIT **sc;
  344.  
  345.     for(sc=SCREEN,i=0;i<YWIDTH;sc++,i++) {
  346.         if (*sc == d) {
  347.             *sc = s;
  348.         }
  349.     }
  350. }
  351.  
  352. /* up0 を見付たら、次の行を up で書き換え、さらにボトムに当たるまで書き直す */
  353. void
  354. disp_replace_after(UNIT *up0, UNIT *up)
  355. {
  356.     register int i;
  357.     register UNIT **sc,*wp;
  358.  
  359.     for(sc=SCREEN,i=0;i<YWIDTH;) {
  360.         if (sc[i] == up0) {
  361.             i++;
  362.             wp = up;
  363.             while(sc[i] != NOT) {
  364.                 disp_1line(i++,wp);
  365.                 if ((wp == TAIL) && (sc[i] != NOT)){
  366.                     disp_1line(i,NIL);
  367.                     break;
  368.                 }
  369.                 wp = wp->ATO;
  370.             }
  371.         } else {
  372.             i++;
  373.         }
  374.     }
  375. }
  376.  
  377. /* SCREN に up0 を見付たら、次の行を up で書き換え、さらにボトムに当たるまで書き直す */
  378. void
  379. disp_replace_after_SCREEN(UNIT *up0, UNIT *up)
  380. {
  381.     register int i;
  382.     register UNIT **sc,*wp;
  383.  
  384.     for(sc=SCREEN,i=0;i<YWIDTH;) {
  385.         if (sc[i] == up0) {
  386.             i++;
  387.             wp = up;
  388.             while(sc[i] != NOT) {
  389.                 sc[i++] = wp;
  390.                 if ((wp == TAIL) && (sc[i] != NOT)){
  391.                     sc[i] = NIL;
  392.                     break;
  393.                 }
  394.                 wp = wp->ATO;
  395.             }
  396.         } else {
  397.             i++;
  398.         }
  399.     }
  400. }
  401.  
  402. /* 指定されたウィンドウを、top を最上行として書き直す */
  403. void
  404. disp_window_top_flush(int wn,UNIT *top)
  405. {
  406.     int i;
  407.  
  408.     for(i = WDATA[wn].WY0;i <= WDATA[wn].WY1;i++) {
  409.         disp_1line(i,top);
  410.         if (top) {
  411.             if (top == TAIL) {
  412.                 top = NIL;
  413.             } else {
  414.                 top = top->ATO;
  415.             }
  416.         }
  417.     }
  418.     disp_btm_line(wn);
  419. }
  420.  
  421. /* すべてのウインドウを描き直す。ただし、ボトムはいじらない */
  422. void
  423. disp_all_window_redraw()
  424. {
  425.     register int i;
  426.     register UNIT *p;
  427.  
  428.     for(i=0;i<YWIDTH-1;i++) {
  429.         if ((p = SCREEN[i]) != NOT) {
  430.             disp_1line(i,p);
  431.         }
  432.     }
  433.     work_cursor_cpx();
  434. }
  435.  
  436. /* 1行だけ y の位置に表示する */
  437. /* y は絶対座標である */
  438. void
  439. disp_1line_rel_trans0(int x,int y, STR string)
  440. {
  441.     etc_bit_convert_and_disp(x,CWY0+y,string);
  442. }
  443.  
  444. /* 指定された位置から文字列を表示する */
  445. /* y は絶対座標である */
  446. /* 新しい X 座標を返す */
  447. int
  448. disp_half_line(int x,int y,STR s)
  449. {
  450.     return(etc_bit_convert_and_disp(x,y,s));
  451. }
  452.  
  453. /* カレントウインドウの y(相対) の位置に半行表示する */
  454. /* 新しい X 座標を返す */
  455. int
  456. disp_half_line_rel(int x,int y, STR s)
  457. {
  458.     return(disp_half_line(x,CWY0+y,s));
  459. }
  460.  
  461. /* 指定された行を y 座標として、それ以降の画面を書き直す */
  462. /* ちゃんとエコーする */
  463. void
  464. disp_half_flush(UNIT *top,int y)
  465. {
  466.     register int i;
  467.     register int delta = CWY1-CWY0;
  468.  
  469.     for(i = y;i <= delta;i++) {
  470.         disp_1line_rel(i,top);
  471.         if (top) {
  472.             if (top == TAIL) {
  473.                 top = NIL;
  474.             } else {
  475.                 top = top->ATO;
  476.             }
  477.         }
  478.     }
  479. }
  480.  
  481. extern UBYTE koho_10[10+1][MAXLINE];
  482. extern UWORD koho_10x[10+1];
  483.  
  484. /* 候補ブロック( <= 9)を表示する */
  485. int
  486. disp_koho_block(int kn)
  487. {
  488.     register int i;
  489.     int x;
  490.  
  491.     window_abs_loc(0,UNDER_Y+1);
  492.     B_PRINT("\x1b[0K");            /* カーソルから右をクリア */
  493.     x = 0;
  494.     for(i=1;i<=9;i++) {
  495.         if (*koho_10[i]) {        /* 候補があるなら */
  496.             koho_10x[i] = x;
  497.             disp_koho(i,kn,&x,koho_10[i]);
  498.         } else {
  499.             break;
  500.         }
  501.     }
  502. }
  503.  
  504. /* 最下行に候補を表示する */
  505. /* x を更新する */
  506. /* 表示しきれない時は非零を返す */
  507. int
  508. disp_koho(int n,int kn,int *x,STR koho)
  509. {
  510.     UBYTE koho_d[MAXLINE];
  511.  
  512.     window_abs_loc(*x,UNDER_Y+1);
  513.     B_PUTC(n+'0');
  514.     B_PUTC('.');
  515.     if (n == kn) {
  516.         etc_color(10);    /* 選択色 */
  517.     }
  518.     etc_string_esc_cnv(koho,koho_d);
  519.     B_PRINT(koho_d);
  520.     *x = (B_LOCATE(-1,0) >> 16) + 1;
  521.     if (n = kn) {
  522.         etc_color(NORMAL);    /* 戻す */
  523.     }
  524.     return(*x > 80);
  525. }
  526.  
  527. void
  528. disp_cr_mode()
  529. {
  530.     if (CR_VIEW) {
  531.         KAIGYOU_CODE = KAIGYOU0;
  532.         KAIGYOU_HIGH = 0x81;
  533.         KAIGYOU_LOW = 0xde;
  534.     } else {
  535.         KAIGYOU_CODE = L' ';
  536.         KAIGYOU_HIGH = KAIGYOU_CODE >> 8;
  537.         KAIGYOU_LOW = KAIGYOU_CODE & 0xff;
  538.     }
  539. }
  540.  
  541. /* 変えたら非零を返す */
  542. int
  543. disp_tab_change(int a)
  544. {
  545.     if ((a <= 0) || (a > TAB_LENGTH_LIMIT) || (a > CURRENT_JIZUME)) {
  546.         /* 何もしない */
  547.     } else {
  548.         UNIT *wp;
  549.         int bp,y;
  550.  
  551.         etc_set_tab(a);
  552.         line_seigyou();
  553.         under_print((STR)"タブ変更:作業中・・・");
  554.         mark_set_mark(XCODE_SYSMARK - XCODE_MARK + CWN);    /* システムマーク */
  555.         wp = HEAD->ATO;    /* 先頭行 */
  556.         line_arrange_all(wp);
  557.         wp = mark_get_mark(XCODE_SYSMARK - XCODE_MARK + CWN,&bp);
  558.         mark_erase_mark(XCODE_SYSMARK - XCODE_MARK + CWN);    /* システムマークを消す */
  559.         CL = wp;
  560.         line_cl_cl();
  561.         disp_cl_y(CY);
  562.         work_line_analyze();
  563.         CPX = work_byte_to_CPX(bp);
  564.         CX0 = CX = ANALYZE[CPX].XPOS;
  565.         under_blanc();
  566.         return(1);
  567.     }
  568.     return(0);
  569. }
  570.  
  571. /* 1行スクロールアップする */
  572. /* 最後に転送したポインタを返す */
  573. /* はみ出したなら */
  574. UNIT *
  575. disp_scroll_up1()
  576. {
  577.     register int lyw_total,yw;
  578.     register int cwy0,cwy1;
  579.     UNIT *last;
  580.     register int i,j;
  581.  
  582.     lyw_total = LYW_TOTAL/4;
  583.     cwy0 = CWY0;
  584.     last = SCREEN[cwy1 = CWY1];
  585.     if (yw = lyw_total*(cwy1-cwy0)) {    /* スクロールするラスタユニット数 */
  586.         TXRASCPY((cwy0+1)*lyw_total*256+cwy0*lyw_total,yw,0x0003);
  587.         for(i=cwy0,j=cwy0+1;j<=cwy1;i++,j++) {
  588.             SCREEN[i] = SCREEN[j];
  589.         }
  590.         SCREEN[cwy1] = NIL;
  591.     }
  592.     return(last);
  593. }
  594.  
  595. /* 1行スクロールダウンする */
  596. /* 最後に転送したポインタを返す */
  597. UNIT *
  598. disp_scroll_dn1()
  599. {
  600.     register int lyw_total,yw;
  601.     register int cwy0,cwy1;
  602.     UNIT *last;
  603.     register int i,j;
  604.  
  605.     lyw_total = LYW_TOTAL/4;
  606.     last = SCREEN[cwy0 = CWY0];
  607.     cwy1 = CWY1;
  608.     if (yw = lyw_total*(cwy1-cwy0)) {    /* スクロールするラスタユニット数 */
  609.         TXRASCPY((cwy1*lyw_total-1)*256+(cwy1+1)*lyw_total-1,yw,0x8003);
  610.         for(i=cwy1,j=cwy1-1;j>=cwy0;i--,j--) {
  611.             SCREEN[i] = SCREEN[j];
  612.         }
  613.         SCREEN[cwy0] = NIL;
  614.     }
  615.     return(last);
  616. }
  617.  
  618. void
  619. disp_hmode()
  620. {
  621.     register int i;
  622.  
  623.     for(i=0;i<MAX_WINDOW;i++) {
  624.         if (WDATA[i].WY1+2 == UNDER_Y) {
  625.             break;
  626.         }
  627.     }
  628.     disp_btm_line(i);
  629. }
  630.  
  631. /* 最下行に記号候補を表示する */
  632. /* 16個ずつかく */
  633. void
  634. disp_kigou_koho()
  635. {
  636.     int xn;
  637.     UBYTE w[MAXLINE];
  638.     int kigou_block;
  639.     register int i;
  640.     UBYTE spacer[4];
  641.  
  642.     sprintf((char *)w,"[記号入力] <%4X>",kigou_begin);
  643.     window_abs_loc(0,UNDER_Y+1);
  644.     etc_color(MIZU_REV);
  645.     B_PRINT(w);
  646.     window_abs_loc(17,UNDER_Y+1);
  647.     kigou_block = kigou_begin & 0xfff0;
  648.     xn = kigou_begin & 0x000f;
  649.     if (etc_char_disp_len(etc_normal_jis(kigou_begin)) == 1) {
  650.         strcpy(spacer,"   ");
  651.     } else {
  652.         strcpy(spacer,"  ");
  653.     }
  654.     for(i = 0;i<16;i++) {
  655.         etc_color(RAW0);
  656.         B_PRINT(spacer);
  657.         if (i == xn) {
  658.             etc_color(MIZU_REV);
  659.         }
  660.         B_PUTC(etc_normal_jis(kigou_block+i));
  661.     }
  662.     etc_color(NORMAL);
  663.     B_PRINT("\x1b[0K");
  664. }
  665.  
  666. /* 指定位置から文字列 string を表示する */
  667. /* 左側には fl がある */
  668. /* 画面外に出そうになったら、スクロールアップし、その行数を返す */
  669. /* CWY1-CWY0 が最下行 */
  670. int
  671. disp_out_stop(STR fl,int *bx,int *by,STR string)
  672. {
  673.     UBYTE l[VERY_LONG_LINE*4], s[VERY_LONG_LINE*4];
  674.     register int fl_len;
  675.     register int flag;
  676.     register int ly = CWY1-CWY0;
  677.     register int scroll_up_counter = 0;
  678.  
  679.     if (!*string) {
  680.         return(0);
  681.     }
  682.     fl_len = strlen(fl);    /* 左側の長さを調べる */
  683.     cut_2line_link_check(fl,string,fl,s,CURRENT_JIZUME);
  684.                 /* 左側と string を接続してカットする */
  685.  
  686.     if (*s) {    /* 1行ではおさまらなかった(string は2行以上にまたがる) */
  687.         *bx = etc_bit_convert_and_disp(*bx,CWY0+*by,&fl[fl_len]);
  688. #if 0
  689.         *bx = disp_half_line(x,CWY0+y,s);
  690.         *bx = disp_half_line_rel(*bx,*by,&fl[fl_len]);    /* まずは1行表示 */
  691. #endif
  692.         while(*s) {
  693.             if (++(*by) > ly) {    /* ウインドウからはみ出る */
  694.                 register UNIT *uuu;
  695.  
  696.                 scroll_up_counter++;
  697.                 if (CY) {
  698.                     uuu = disp_scroll_up1();
  699.                     SCREEN[CWY1] = uuu->ATO;
  700.                     (*by)--;    /* 戻す */
  701.                     CY--;
  702.                 } else {
  703.                     return(scroll_up_counter);
  704.                 }
  705.             }
  706.             cut_line(s,l,s,CURRENT_JIZUME);
  707. /*etc_beep();*/
  708.             *bx = etc_bit_convert_and_disp(0,CWY0+*by,l);
  709. /*            *bx = disp_half_line_rel(0,*by,l);*/
  710.         }
  711.         strcpy(fl,l);    /* 最後に表示した物を fl とする */
  712.         if (etc_last(fl) == CR) {    /* 最後に表示した行が改行で終わっている */
  713.             (*by)++;        /* 次に表示を開始するのは、もう一行先 */
  714.             *bx = 0;        /* の行頭から */
  715.             *fl = EOS;
  716.         }
  717.         return(scroll_up_counter);
  718.     } else {    /* 1行でおさまった */
  719.         *bx = disp_half_line_rel(*bx,*by,&fl[fl_len]);
  720.         if (etc_last(string) == CR) {
  721.             (*by)++;
  722.             *bx = 0;
  723.             *fl = EOS;
  724.         }
  725.         return(0);
  726.     }
  727. }
  728.  
  729. UWORD CRX,CRY;
  730. UWORD FCR;
  731.  
  732. /* 指定された行のバイト位置を x,y として、それ以降の画面を書き直す */
  733. /* 見える範囲内だけ、超特急で書く */
  734. /* もちろんカレントウインドウだけ */
  735. /* 多少いい加減でも速度の方を優先 */
  736. /* TEXT に反映しない */
  737. /* あとでエコーするでしょ */
  738. /* TBUFF_R が最初にある */
  739. /* 改行で節約できたらする */
  740. void
  741. disp_trans_half_flush(UNIT *p0,int bp,int x,int y)/* ,,, */
  742.     UBYTE l[VERY_LONG_LINE*8], s[VERY_LONG_LINE*8];
  743.     register UNIT *p;
  744.     register int flag;
  745.     register UWORD c;
  746.     int y0;
  747.  
  748.     FCR = 1;
  749.     p = p0;
  750.     *l = EOS;
  751.     CUT_GETA = x;        /* フラッシュの開始点 */
  752.     y0 = y;
  753.  
  754.     while(SCREEN[CWY0+y0] != p) {
  755.         y0--;
  756.         if ((y0 < 0) || (CWY0+y0 < 0)) {
  757.             y0 = y;
  758.             while(SCREEN[CWY0+y0] != p) {
  759.                 y0++;
  760.             }
  761.             break;
  762.         }
  763.     }
  764.  
  765.     for(;y0 <= y;y0++) {
  766.         if (p == TAIL) {
  767.             break;
  768.         }
  769.         line_cat_body(l,p);
  770.         p = p->ATO;
  771.     }
  772.  
  773.     if (p != TAIL) {
  774.         line_cat_body(l,p);
  775.     }
  776. /*under_print(l);binkey();*/
  777. /*    p = p0;*/
  778.  
  779.     if (x >= CURRENT_JIZUME) {
  780.         if (l[bp] != CR) {
  781.             x = 0;
  782.             if (++y > (CWY1-CWY0)) {    /* いきなり画面外である */
  783.                 CUT_GETA = 0;
  784.                 return;
  785.             }
  786.         }
  787.     }
  788.  
  789.     flag = cut_line(&l[bp],s,l,CURRENT_JIZUME-x);    /* 最初の半行 */
  790.     if (((c = etc_last(s)) == CR) || flag) {    /* 余りがある=完全に一行が取れた */
  791. /*        disp_1line_rel_trans0(x,y,s);*/
  792. /*        CUT_GETA = 0;*/
  793.         if (c == CR) {    /* !!!改行を書こうとしている */
  794.             if (CRX) {    /* 既に書いた */
  795.                 if (CRY == y) {    /* 前回と同じ行に改行を書く */
  796.                     disp_1line_rel_trans0(x,y,s);
  797.                     CUT_GETA = 0;
  798.                     return;
  799.                 } else {    /* 最初の改行が移動した? */
  800.                     if (FCR) {
  801.                         if (!x && (y == CRY+1)) {
  802.                     /* x が非零ならば、未変換を左に持つ行かも知れない */
  803.                             disp_trans_scroll_dn1(y);
  804.                             disp_1line_rel_trans0(x,y,s);
  805.                             CRY = y;
  806.                             return;
  807.                         }
  808.                         CRY = y;    /* 続行 */
  809.                     }
  810.                 }
  811.             } else {        /* まだ書いてない */
  812.                 CRX = 1;
  813.                 CRY = y;
  814.             }
  815.             FCR = 0;
  816.         }
  817.         disp_1line_rel_trans0(x,y,s);
  818.         CUT_GETA = 0;
  819. #if 0
  820.         if (!flag && (c == CR)) {
  821. window0();printf("[%d][%d]",y0,y);
  822.             return;
  823.         }
  824. #endif
  825.         if (p != TAIL) {
  826.             p = p->ATO;
  827.         }
  828. #if 0
  829.         if (p == TAIL) {    /* 末行だ,,,, */
  830.             line_append1(p = line_get_free());
  831.         } else {
  832.             p = p->ATO;
  833.         }
  834.         /* これ以降、p の先頭に l を挿入すれば良い */
  835. #endif
  836.     } else {
  837.         strcpy(l,s);    /* 戻す */
  838.         p = p->ATO;
  839.         if ((p == TAIL) || (!p)) {    /* もう後の行は無い */
  840.             disp_1line_rel_trans0(x,y,l);
  841.             CUT_GETA = 0;
  842.             /* ウインドウ最下行までを消して終了 */
  843.             for(y++;y <= (CWY1-CWY0);y++) {
  844.                 disp_half_line_rel(0,y,(STR) "");
  845.             }
  846.             return;
  847.         }
  848.         line_cat_body(l,p);    /* 次の行を追加する */
  849. #if 0
  850.         flag = cut_line(&l[bp],s,l,CURRENT_JIZUME-x);    /* 最初の半行 */
  851. #else
  852.         flag = cut_line(l,s,l,CURRENT_JIZUME-x);    /* 最初の半行 */
  853. #endif                        /* flag = strlrn(l) */
  854.         if (((c = etc_last(s)) == CR) || flag) {
  855.                 /* 余りがある=完全に一行が取れた */
  856. /*            disp_1line_rel_trans0(x,y,s);*/
  857. /*            CUT_GETA = 0;*/
  858.             if (c == CR) {    /* !!!改行を書こうとしている */
  859.                 if (CRX | CRY) {    /* 既に書いた */
  860.                     if (CRY == y) {    /* 前回と同じ行に改行を書く */
  861.                         disp_1line_rel_trans0(x,y,s);
  862.                         CUT_GETA = 0;
  863.                         return;
  864.                     } else {
  865.                         if (FCR) {
  866.                             if (y == CRY+1) {
  867.                                 disp_trans_scroll_dn1(y);
  868.                                 disp_1line_rel_trans0(x,y,s);
  869.                                 CRY = y;
  870.                                 return;
  871.                             }
  872.                             CRY = y;    /* 続行 */
  873.                         }
  874.                     }
  875.                 } else {        /* まだ書いてない */
  876.                     CRX = 1;
  877.                     CRY = y;
  878.                 }
  879.                 FCR = 0;
  880.             }
  881.             disp_1line_rel_trans0(x,y,s);
  882.             CUT_GETA = 0;
  883. #if 0
  884.             if (flag == i) {
  885. etc_beep();etc_beep();
  886.                 return;
  887.             }
  888. #endif
  889.             p = p->ATO;
  890.             /* これ以降、p の先頭に l を挿入すれば良い */
  891.         } else {
  892.             /* 出入りが無かったのだから、これで終わり */
  893.             disp_1line_rel_trans0(x,y,s);
  894. #if 1
  895.             CUT_GETA = 0;
  896.             return;
  897. #endif
  898.         }
  899.     }
  900.     CUT_GETA = 0;    /* ダメ押し */
  901.     y++;
  902.     disp_line_wave(p,y,l);
  903. }
  904.  
  905. UBYTE ccc = 15;
  906.  
  907. /* up の指す行(位置は y)の行頭に s を挿入し、次々に送って行く */
  908. /* エコーしない */
  909. /* テキストに反映しない */
  910. /* 改行で節約できたらする */
  911. void
  912. disp_line_wave(UNIT *up,int y,STR s)
  913. {
  914.     UBYTE l[VERY_LONG_LINE*8],t[VERY_LONG_LINE*8];
  915.     register UNIT *wp = up;
  916.     register int i;
  917.     register int ly;
  918.  
  919.     if (y > (ly = (CWY1-CWY0))) {
  920.         return;
  921.     }
  922.  
  923. /*
  924. window0();
  925. printf("[%s][%s]",s,up->BODY);binkey();
  926. */
  927. /*etc_color(ccc);if (ccc == 15) ccc = 14; else ccc = 15;*/
  928.     strcpy(l,s);
  929.     if (wp != TAIL) {
  930.         line_cat_body(l,wp);
  931.     }
  932.     while(y <= ly) {
  933. /* s1 -> s2(切り出し)+ s3(余り)s1 == s3 でもOK */
  934.         if (cut_line(l,t,l,CURRENT_JIZUME)) {    /* 余りの長さを返す */
  935. /*            etc_bit_convert_and_disp(0,CWY0+y,t);*/
  936.             if (etc_last(t) == CR) {    /* !!!改行を書こうとしている */
  937.                 if (CRX | CRY) {    /* 既に書いた */
  938.                     if (CRY == y) {    /* 前回と同じ行に改行を書く */
  939.                         etc_bit_convert_and_disp(0,CWY0+y,t);
  940.                         return;
  941.                     } else {
  942.                         if (FCR) {
  943.                             if (y == CRY+1) {
  944.                                 disp_trans_scroll_dn1(y);
  945.                                 etc_bit_convert_and_disp(0,CWY0+y,t);
  946.                                 CRY = y;
  947.                                 return;
  948.                             }
  949.                             CRY = y;    /* 続行 */
  950.                         }
  951.                     }
  952.                 } else {        /* まだ書いてない */
  953.                     CRX = 1;
  954.                     CRY = y;
  955.                 }
  956.                 FCR = 0;
  957.             }
  958.             etc_bit_convert_and_disp(0,CWY0+y,t);
  959.             if (wp != TAIL) {
  960.                 wp = wp->ATO;
  961.                 line_cat_body(l,wp);
  962.             }
  963.         } else {            /* 余りが無い */
  964. /*            etc_bit_convert_and_disp(0,CWY0+y,t);*/
  965.             if (etc_last(t) == CR) {    /* !!!改行を書こうとしている */
  966.                 if (CRX | CRY) {    /* 既に書いた */
  967.                     if (CRY == y) {    /* 前回と同じ行に改行を書く */
  968.                         etc_bit_convert_and_disp(0,CWY0+y,t);
  969.                         return;
  970.                     } else {
  971.                         if (FCR) {
  972.                             if (y == CRY+1) {
  973.                                 disp_trans_scroll_dn1(y);
  974.                                 etc_bit_convert_and_disp(0,CWY0+y,t);
  975.                                 CRY = y;
  976.                                 return;
  977.                             }
  978.                             CRY = y;    /* 続行 */
  979.                         }
  980.                     }
  981.                 } else {        /* まだ書いてない */
  982.                     CRX = 1;
  983.                     CRY = y;
  984.                 }
  985.                 FCR = 0;
  986.             }
  987.             etc_bit_convert_and_disp(0,CWY0+y,t);
  988.             wp = wp->ATO;
  989.             if ((!wp) || (wp == TAIL)) {
  990.                     /* ウインドウ最下行までを消して終了 */
  991.                 for(++y;y <= (CWY1-CWY0);y++) {
  992.                     etc_bit_convert_and_disp(0,CWY0+y,(STR)"");
  993.                 }
  994.                 break;            /* 終了 */
  995.             } else {
  996.                 line_cat_body(l,wp);
  997.             }
  998.         }
  999.         y++;
  1000.     }
  1001. /*error("5");*/
  1002.  
  1003. }
  1004.  
  1005. /* y 行から下を n 行スクロールダウンする */
  1006. /* y は相対 */
  1007. void
  1008. disp_trans_scroll_dn1(int y)
  1009. {
  1010.     register int lyw_total,yw;
  1011.     register int wy0,wy1;
  1012.  
  1013.     UBYTE w[MAXLINE];
  1014.  
  1015. /*sprintf(w,"(%d)(%d)",y,n);under_print(w);binkey();*/
  1016.     lyw_total = LYW_TOTAL/4;
  1017.     wy0 = CWY0 + y;
  1018.     wy1 = CWY1;
  1019.     if (yw = lyw_total*(wy1-wy0)) {    /* スクロールするラスタユニット数 */
  1020. /*        TXRASCPY(((wy1-n+1)*lyw_total-1)*256 + (wy1+1)*lyw_total-1,yw,0x8003);*/
  1021.         TXRASCPY((wy1*lyw_total-1)*256+(wy1+1)*lyw_total-1,yw,0x8003);
  1022.     }
  1023. }
  1024.  
  1025.  
  1026. void
  1027. disp_trim_tail()
  1028. {
  1029.     register int i;
  1030.  
  1031.     i = 0;
  1032.     while(1) {
  1033.         if (i == YWIDTH0) {    /* 絶対的最後 */
  1034.             return;
  1035.         }
  1036.         if (SCREEN[i] == TAIL) {
  1037.             i++;
  1038.             while(SCREEN[i] == TAIL) {
  1039.                 SCREEN[i++] = NULL;
  1040.                 if (i == YWIDTH0) {    /* 絶対的最後 */
  1041.                     return;
  1042.                 }
  1043.             }
  1044.         } else {
  1045.             i++;
  1046.         }
  1047.     }
  1048. }
  1049.